当前位置:  开发笔记 > 编程语言 > 正文

使`std :: get`与SFINAE一起玩得很好

如何解决《使`std::get`与SFINAE一起玩得很好》经验,为你挑选了2个好方法。

std::get 似乎不是SFINAE友好的,如下面的测试用例所示:

template 
auto foo(C &c) -> decltype(std::get(c)) {
    return std::get(c);
}

template 
void foo(...) { }

int main() {
    std::tuple tuple{42};

    foo(tuple);    // Works fine
    foo(tuple); // Crashes and burns
}

在Coliru上看到它

目标是将第二次呼叫foo转向第二次超载.在实践中,libstdc ++给出:

/usr/local/bin/../lib/gcc/x86_64-pc-linux-gnu/6.3.0/../../../../include/c++/6.3.0/tuple:1290:14: fatal error: no matching function for call to '__get_helper2'
    { return std::__get_helper2<_Tp>(__t); }
             ^~~~~~~~~~~~~~~~~~~~~~~

libc ++更直接,直接static_assert引爆:

/usr/include/c++/v1/tuple:801:5: fatal error: static_assert failed "type not found in type list"
    static_assert ( value != -1, "type not found in type list" );
    ^               ~~~~~~~~~~~

我真的不想实现洋葱层检查是否C是一个std::tuple专业化,并寻找T其参数内...

有没有理由std::get不对SFINAE友好?有没有比上面概述的更好的解决方法?

我发现了一些事情std::tuple_element,但没有std::get.



1> Barry..:

std::get 根据[tuple.elem]显然不是SFINAE友好的:

template 
  constexpr T& get(tuple& t) noexcept;
// and the other like overloads

要求:类型T恰好出现一次Types....否则,该计划是不正确的.

std::get 也明确不是SFINAE友好的.


至于其他问题:

有没有理由std::get不对SFINAE友好?

不知道.通常,这不是需要SFINAE编辑的一点.所以我想这不是需要做的事情.滚动查看一堆不可行的候选选项,比较容易理解硬错误.如果您认为有令人信服的理由对std::getSFINAE友好,您可以提交LWG问题.

有没有比上面概述的更好的解决方法?

当然.您可以编写自己的SFINAE友好版本get(请注意,它使用C++ 17 倍表达式):

template ::value + ...) == 1, int> = 0>
constexpr T& my_get(tuple& t) noexcept {
    return std::get(t);
}

然后按照你的意愿去做.



2> Yakk - Adam ..:

不要SFINAE上std::get; 这是不允许的.

以下是两种相对友好的方法来测试你是否可以using std::get; get(t):

template
using can_get=std::integral_constant::value>;

namespace helper{
  template
  struct can_get_type:std::false_type{};
  template
  struct can_get_type>:
    std::integral_constant+...)==1>
  {};
}
template
using can_get=typename helpers::can_get_type::type;

那你的代码是:

template {},int> =0>
decltype(auto) foo(C &c) {
  return std::get(c);
}

推荐阅读
kikokikolove
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有